package cn.imnaer.service.rpc.friendcircle.dao;

import cn.imnaer.database.BaseDao;
import cn.imnaer.database.MatchConst;
import cn.imnaer.database.define.DBConstant;
import cn.imnaer.service.persistence.model.FriendCircle;
import cn.imnaer.service.persistence.model.consts.FRIENDCIRCLE;
import cn.imnaer.service.rpc.enums.EnumFriendCircleType;

import org.bson.BSONObject;
import org.bson.BasicBSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2015/5/7.
 *
 * @see cn.imnaer.service.persistence.model.FriendCircle
 */
public class FriendCircleDaoImpl extends BaseDao<FriendCircle> {

	private static final FriendCircleDaoImpl FRIEND_ACTIVE_RECORD = new FriendCircleDaoImpl();

	private FriendCircleDaoImpl() {
		
		
	}

	public static FriendCircleDaoImpl getInstance() {
		return FriendCircleDaoImpl.FRIEND_ACTIVE_RECORD;
	}

	@Override
	protected String getDbSpaceName() {
		// TODO Auto-generated method stub
		return DBConstant.SPACE.FRIEND_CIRCLE_INFO_SPACE;
	}

	@Override
	protected String getDbCollectionName() {
		// TODO Auto-generated method stub
		return DBConstant.COLLECTION.FRIEND_CIRCLE_INFO_COLLECTION;
	}

	@Override
	protected String getPrimaryKey() {
		// TODO Auto-generated method stub
		return FRIENDCIRCLE.friendCircleId;
	}
	/**
	 * 根据标准时间戳, 返回玩伴信息
	 *
	 * @param userId
	 *            玩伴用户ID
	 * @param criteriaTime
	 *            标准时间戳
	 * @param isUpdate
	 *            <p>
	 *            true : 拉取标准时间戳之后的数据 false : 拉取标准时间戳之前的数据 (10) 条
	 *            </p>
	 * @return
	 */
	public List<FriendCircle> findByUserIdAndCriteriaTime(String userId,
			long criteriaTime, boolean isUpdate, EnumFriendCircleType... types) {

		ArrayList<String> userIds = new ArrayList<String>();
		userIds.add(userId);
		return this.findByUserIdsAndCriteriaTime(userIds, criteriaTime,
				isUpdate, types);
	}

	public List<FriendCircle> findByUserIdsAndCriteriaTime(
			List<String> userIds, long criteriaTime, boolean isUpdate,
			EnumFriendCircleType... types) {

		BSONObject query = new BasicBSONObject();
		BSONObject order = new BasicBSONObject();
		if (types != null && types.length == 1) {

			query.put(FRIENDCIRCLE.type, types[0].getValue());
		} else if (types != null && types.length > 1) {

			List<String> friendCircleTypes = new ArrayList<>();
			List<BasicBSONObject> typesQuery = new ArrayList<>();
			for (EnumFriendCircleType type : types) {
				friendCircleTypes.add(type.getValue());
				BasicBSONObject typeQuery = new BasicBSONObject();
				typeQuery.put(FRIENDCIRCLE.type, type.getValue());
				typesQuery.add(typeQuery);
			}
			query.put(MatchConst._OR, typesQuery);
		}

		if (userIds != null && userIds.size() == 1) {
			query.put(FRIENDCIRCLE.userId, userIds.get(0));
		} else if (userIds != null && userIds.size() > 1) {
			BSONObject matcher = new BasicBSONObject();
			matcher.put(MatchConst._IN, userIds);
			query.put(FRIENDCIRCLE.userId, matcher);
		}
		order.put(FRIENDCIRCLE.createTime, -1);

		List<FriendCircle> result = this.queryWithCriteriaTime(
                criteriaTime, isUpdate, query, order);
		return result;
	}

	public List<FriendCircle> findByUserIdsAndScenicId(List<String> userIds,
			List<String> scenicIds, long criteriaTime, boolean isUpdate,
			EnumFriendCircleType... types) {

		BSONObject query = new BasicBSONObject();
		BSONObject order = new BasicBSONObject();
		if (types != null && types.length == 1) {

			query.put(FRIENDCIRCLE.type, types[0].getValue());
		} else if (types != null && types.length > 1) {

			List<String> friendCircleTypes = new ArrayList<>();
			List<BasicBSONObject> typesQuery = new ArrayList<>();
			for (EnumFriendCircleType type : types) {
				friendCircleTypes.add(type.getValue());
				BasicBSONObject typeQuery = new BasicBSONObject();
				typeQuery.put(FRIENDCIRCLE.type, type.getValue());
				typesQuery.add(typeQuery);
			}
			query.put(MatchConst._OR, typesQuery);
		}

		if (userIds != null && userIds.size() == 1) {
			query.put(FRIENDCIRCLE.userId, userIds.get(0));
		} else if (userIds != null && userIds.size() > 1) {
			BSONObject matcher = new BasicBSONObject();
			matcher.put(MatchConst._IN, userIds);
			query.put(FRIENDCIRCLE.userId, matcher);
		}

		if (scenicIds != null) {
			BSONObject matcher = new BasicBSONObject();
			matcher.put(MatchConst._IN, scenicIds);
			query.put(FRIENDCIRCLE.containScenicIds, matcher);
		}

		order.put(FRIENDCIRCLE.createTime, -1);

		List<FriendCircle> result = this.queryWithCriteriaTime(
                criteriaTime, isUpdate, query, order);
		return result;
	}

	public FriendCircle getFirstByUserIdsAndScenicId(List<String> userIds,
			List<String> scenicIds, EnumFriendCircleType... types) {

		BSONObject query = new BasicBSONObject();
		BSONObject order = new BasicBSONObject();
		if (types != null && types.length == 1) {

			query.put(FRIENDCIRCLE.type, types[0].getValue());
		} else if (types != null && types.length > 1) {

			List<String> friendCircleTypes = new ArrayList<>();
			List<BasicBSONObject> typesQuery = new ArrayList<>();
			for (EnumFriendCircleType type : types) {
				friendCircleTypes.add(type.getValue());
				BasicBSONObject typeQuery = new BasicBSONObject();
				typeQuery.put(FRIENDCIRCLE.type, type.getValue());
				typesQuery.add(typeQuery);
			}
			query.put(MatchConst._OR, typesQuery);
		}

		if (userIds != null && userIds.size() == 1) {
			query.put(FRIENDCIRCLE.userId, userIds.get(0));
		} else if (userIds != null && userIds.size() > 1) {
			BSONObject matcher = new BasicBSONObject();
			matcher.put(MatchConst._IN, userIds);
			query.put(FRIENDCIRCLE.userId, matcher);
		}

		if (scenicIds != null) {
			BSONObject matcher = new BasicBSONObject();
			matcher.put(MatchConst._IN, scenicIds);
			query.put(FRIENDCIRCLE.containScenicIds, matcher);
		}

		order.put(FRIENDCIRCLE.createTime, -1);

		FriendCircle result = null;
		try {
			result = this.findOne(query, order);

		} catch (Exception e) {
			// e.printStackTrace();
		}
		return result;
	}

	/**
	 * 根据标准时间戳查询
	 *
	 * @param criteriaTime
	 *            标准时间戳
	 * @param isUpdate
	 *            <p>
	 *            true : 拉取标准时间戳之后的数据 false : 拉取标准时间戳之前的数据 (10) 条
	 *            </p>
	 * @param query
	 *            查询
	 * @param order
	 *            排序
	 * @return
	 */
	private List<FriendCircle> queryWithCriteriaTime(
            long criteriaTime, boolean isUpdate, BSONObject query,
            BSONObject order) {
		List<FriendCircle> result;
		if (isUpdate) { // 代表拉去最新的数据, 应该返回标准时间戳之后的数据 (最大500条)
			BSONObject match = new BasicBSONObject();
			match.put(MatchConst._GT, criteriaTime);
			query.put(FRIENDCIRCLE.createTime, match);
			result = this.findAll(query, order, 500);

		} else { // 代表拉旧数据 返回标准时间戳之前的10条

			BSONObject match = new BasicBSONObject();
			match.put(MatchConst._LT, criteriaTime);
			query.put(FRIENDCIRCLE.createTime, match);

			result = this.findAll(query, order, 10);
		}

		return result;
	}

	public boolean deleteByTypeAndItemId(String itemId, String type) {
		BSONObject query = new BasicBSONObject();
		query.put(FRIENDCIRCLE.type, type);
		query.put(FRIENDCIRCLE.itemId, itemId);
		try {
			this.delete(query);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}



}
